/*
 * drivers/video/tegra/nvdisp/nvdisp_config.c
 *
 * Copyright (c) 2014-2017, NVIDIA CORPORATION, All rights reserved.
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
 * more details.
 *
 * You should have received a copy of the GNU General Public License along
 * with this program; if not, write to the Free Software Foundation, Inc.,
 * 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
 */

#include "dc_config.h"

#define TEGRA_WIN_FMT_T186_W0		( \
	BIT(TEGRA_DC_EXT_FMT_T_P8) | \
	BIT(TEGRA_DC_EXT_FMT_T_A1R5G5B5) | \
	BIT(TEGRA_DC_EXT_FMT_T_R5G6B5) | \
	BIT(TEGRA_DC_EXT_FMT_T_R5G5B5A1) | \
	BIT(TEGRA_DC_EXT_FMT_T_R4G4B4A4) | \
	BIT(TEGRA_DC_EXT_FMT_T_A8R8G8B8) | \
	BIT(TEGRA_DC_EXT_FMT_T_A8B8G8R8) | \
	BIT(TEGRA_DC_EXT_FMT_T_U8_Y8__V8_Y8) | \
	BIT(TEGRA_DC_EXT_FMT_T_Y8___U8___V8_N420))

#define TEGRA_WIN_FMT_T186_W1		( \
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___U8___V8_N444) | \
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___V8U8_N420) | \
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___U8V8_N422) | \
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___V8U8_N422) | \
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___U8V8_N422R) |	\
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___V8U8_N422R) |	\
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8_U8__Y8_V8) | \
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___U8V8_N444) |	\
	BITWORD1(TEGRA_DC_EXT_FMT_T_Y8___V8U8_N444))

#define TEGRA_WIN_FMT_T186_W2					\
	(BITWORD2(TEGRA_DC_EXT_FMT_T_A2R10G10B10) |		\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_A2B10G10R10) |		\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_R16_G16_B16_A16) |		\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_Y10___U10___V10_N420) |	\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_Y10___U10___V10_N444) |	\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_Y10___V10U10_N420) |		\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_Y10___U10V10_N422) |		\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_Y10___U10V10_N422R) |		\
	 BITWORD2(TEGRA_DC_EXT_FMT_T_Y10___U10V10_N444))

#define TEGRA_WIN_FMT_T186_W3					\
	(BITWORD3(TEGRA_DC_EXT_FMT_T_Y12___U12___V12_N420) |	\
	 BITWORD3(TEGRA_DC_EXT_FMT_T_Y12___U12___V12_N444) |	\
	 BITWORD3(TEGRA_DC_EXT_FMT_T_Y12___V12U12_N420) |		\
	 BITWORD3(TEGRA_DC_EXT_FMT_T_Y12___U12V12_N422) |		\
	 BITWORD3(TEGRA_DC_EXT_FMT_T_Y12___U12V12_N422R) |		\
	 BITWORD3(TEGRA_DC_EXT_FMT_T_Y12___U12V12_N444))

#define TEGRA_WIN_FMT_T186_W4					\
	(BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y10___U10V10_N420) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y10___V10U10_N422) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y10___V10U10_N422R) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y10___V10U10_N444) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y12___U12V12_N420) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y12___V12U12_N422) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y12___V12U12_N422R) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y12___V12U12_N444) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y10___V10___U10_N420) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y10___V10___U10_N444) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y12___V12___U12_N420) |	\
	 BITWORD_SW_FORMAT(TEGRA_DC_EXT_FMT_T_Y12___V12___U12_N444))

/* for windows that support compression */
#define TEGRA_WIN_FMT_COMPRESSION_T186_LOW (BIT(TEGRA_DC_EXT_FMT_T_A8R8G8B8) | \
				BIT(TEGRA_DC_EXT_FMT_T_A8B8G8R8))
#define TEGRA_WIN_FMT_COMPRESSION_T186_HIGH  (0)

/* for windows that can't support planar rotation */
#define TEGRA_WIN_FMT_ROTATION_T186_LOW TEGRA_WIN_FMT_BASE
#define TEGRA_WIN_FMT_ROTATION_T186_HIGH (0)


static struct tegra_dc_feature_entry t186_feature_entries_a[] = {
/* window 0 */
	{ 0, TEGRA_DC_FEATURE_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1,
			  TEGRA_WIN_FMT_T186_W2, TEGRA_WIN_FMT_T186_W3,
			  TEGRA_WIN_FMT_T186_W4 } },
	{ 0, TEGRA_DC_FEATURE_BLEND_TYPE, {2} },
	{ 0, TEGRA_DC_FEATURE_MAXIMUM_SIZE, {32767, 1, 32767, 1} },
	{ 0, TEGRA_DC_FEATURE_MAXIMUM_SCALE, {2, 2, 2, 2} },
	{ 0, TEGRA_DC_FEATURE_FILTER_TYPE, {1, 1} },
	{ 0, TEGRA_DC_FEATURE_LAYOUT_TYPE, {1, 0, 1} },
	{ 0, TEGRA_DC_FEATURE_INVERT_TYPE, {1, 1, 1} }, /* SCAN_COLUMN=true */
	{ 0, TEGRA_DC_FEATURE_FIELD_TYPE, {1} },
	{ 0, TEGRA_DC_FEATURE_COMPRESSION_FORMATS,
		{ TEGRA_WIN_FMT_COMPRESSION_T186_LOW,
		TEGRA_WIN_FMT_COMPRESSION_T186_HIGH } },
	{ 0, TEGRA_DC_FEATURE_PLANAR_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
	{ 0, TEGRA_DC_FEATURE_ROTATION_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1 } },
	{ 0, TEGRA_DC_FEATURE_PACKED_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
/* window 1 */
	{ 1, TEGRA_DC_FEATURE_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1,
			  TEGRA_WIN_FMT_T186_W2, TEGRA_WIN_FMT_T186_W3,
			  TEGRA_WIN_FMT_T186_W4 } },
	{ 1, TEGRA_DC_FEATURE_BLEND_TYPE, {2} },
	{ 1, TEGRA_DC_FEATURE_MAXIMUM_SIZE, {32767, 1, 32767, 1} },
	{ 1, TEGRA_DC_FEATURE_MAXIMUM_SCALE, {2, 2, 2, 2} },
	{ 1, TEGRA_DC_FEATURE_FILTER_TYPE, {1, 1} },
	{ 1, TEGRA_DC_FEATURE_LAYOUT_TYPE, {1, 0, 1} },
	{ 1, TEGRA_DC_FEATURE_INVERT_TYPE, {1, 1, 1} }, /* SCAN_COLUMN=true */
	{ 1, TEGRA_DC_FEATURE_FIELD_TYPE, {1} },
	{ 1, TEGRA_DC_FEATURE_COMPRESSION_FORMATS,
		{ TEGRA_WIN_FMT_COMPRESSION_T186_LOW,
		TEGRA_WIN_FMT_COMPRESSION_T186_HIGH } },
	{ 1, TEGRA_DC_FEATURE_PLANAR_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
	{ 1, TEGRA_DC_FEATURE_ROTATION_FORMATS,
			{ TEGRA_WIN_FMT_ROTATION_T186_LOW,
			TEGRA_WIN_FMT_ROTATION_T186_HIGH } },
	{ 1, TEGRA_DC_FEATURE_PACKED_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
/* window 2 */
	{ 2, TEGRA_DC_FEATURE_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1,
			  TEGRA_WIN_FMT_T186_W2, TEGRA_WIN_FMT_T186_W3,
			  TEGRA_WIN_FMT_T186_W4 } },
	{ 2, TEGRA_DC_FEATURE_BLEND_TYPE, {2} },
	{ 2, TEGRA_DC_FEATURE_MAXIMUM_SIZE, {32767, 1, 32767, 1} },
	{ 2, TEGRA_DC_FEATURE_MAXIMUM_SCALE, {2, 2, 2, 2} },
	{ 2, TEGRA_DC_FEATURE_FILTER_TYPE, {1, 1} },
	{ 2, TEGRA_DC_FEATURE_LAYOUT_TYPE, {1, 0, 1} },
	{ 2, TEGRA_DC_FEATURE_INVERT_TYPE, {1, 1, 1} }, /* SCAN_COLUMN=true */
	{ 2, TEGRA_DC_FEATURE_FIELD_TYPE, {1} },
	{ 2, TEGRA_DC_FEATURE_COMPRESSION_FORMATS,
		{ TEGRA_WIN_FMT_COMPRESSION_T186_LOW,
		TEGRA_WIN_FMT_COMPRESSION_T186_HIGH } },
	{ 2, TEGRA_DC_FEATURE_PLANAR_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
	{ 2, TEGRA_DC_FEATURE_ROTATION_FORMATS,
			{ TEGRA_WIN_FMT_ROTATION_T186_LOW,
			TEGRA_WIN_FMT_ROTATION_T186_HIGH } },
	{ 2, TEGRA_DC_FEATURE_PACKED_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
/* window 3 */
	{ 3, TEGRA_DC_FEATURE_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1,
			  TEGRA_WIN_FMT_T186_W2, TEGRA_WIN_FMT_T186_W3,
			  TEGRA_WIN_FMT_T186_W4 } },
	{ 3, TEGRA_DC_FEATURE_BLEND_TYPE, {2} },
	{ 3, TEGRA_DC_FEATURE_MAXIMUM_SIZE, {32767, 1, 32767, 1} },
	{ 3, TEGRA_DC_FEATURE_MAXIMUM_SCALE, {2, 2, 2, 2} },
	{ 3, TEGRA_DC_FEATURE_FILTER_TYPE, {1, 1} },
	{ 3, TEGRA_DC_FEATURE_LAYOUT_TYPE, {1, 0, 1} },
	{ 3, TEGRA_DC_FEATURE_INVERT_TYPE, {1, 1, 1} }, /* SCAN_COLUMN=true */
	{ 3, TEGRA_DC_FEATURE_FIELD_TYPE, {1} },
	{ 3, TEGRA_DC_FEATURE_COMPRESSION_FORMATS,
		{ TEGRA_WIN_FMT_COMPRESSION_T186_LOW,
		TEGRA_WIN_FMT_COMPRESSION_T186_HIGH } },
	{ 3, TEGRA_DC_FEATURE_PLANAR_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
	{ 3, TEGRA_DC_FEATURE_ROTATION_FORMATS,
			{ TEGRA_WIN_FMT_ROTATION_T186_LOW,
			TEGRA_WIN_FMT_ROTATION_T186_HIGH } },
	{ 3, TEGRA_DC_FEATURE_PACKED_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
/* window 4 */
	{ 4, TEGRA_DC_FEATURE_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1,
			  TEGRA_WIN_FMT_T186_W2, TEGRA_WIN_FMT_T186_W3,
			  TEGRA_WIN_FMT_T186_W4 } },
	{ 4, TEGRA_DC_FEATURE_BLEND_TYPE, {2} },
	{ 4, TEGRA_DC_FEATURE_MAXIMUM_SIZE, {32767, 1, 32767, 1} },
	{ 4, TEGRA_DC_FEATURE_MAXIMUM_SCALE, {2, 2, 2, 2} },
	{ 4, TEGRA_DC_FEATURE_FILTER_TYPE, {1, 1} },
	{ 4, TEGRA_DC_FEATURE_LAYOUT_TYPE, {1, 0, 1} },
	{ 4, TEGRA_DC_FEATURE_INVERT_TYPE, {1, 1, 1} }, /* SCAN_COLUMN=true */
	{ 4, TEGRA_DC_FEATURE_FIELD_TYPE, {1} },
	{ 4, TEGRA_DC_FEATURE_COMPRESSION_FORMATS,
		{ TEGRA_WIN_FMT_COMPRESSION_T186_LOW,
		TEGRA_WIN_FMT_COMPRESSION_T186_HIGH } },
	{ 4, TEGRA_DC_FEATURE_PLANAR_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
	{ 4, TEGRA_DC_FEATURE_ROTATION_FORMATS,
			{ TEGRA_WIN_FMT_ROTATION_T186_LOW,
			TEGRA_WIN_FMT_ROTATION_T186_HIGH } },
	{ 4, TEGRA_DC_FEATURE_PACKED_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
/* window 5 */
	{ 5, TEGRA_DC_FEATURE_FORMATS,
			{ TEGRA_WIN_FMT_T186_W0, TEGRA_WIN_FMT_T186_W1,
			  TEGRA_WIN_FMT_T186_W2, TEGRA_WIN_FMT_T186_W3,
			  TEGRA_WIN_FMT_T186_W4 } },
	{ 5, TEGRA_DC_FEATURE_BLEND_TYPE, {2} },
	{ 5, TEGRA_DC_FEATURE_MAXIMUM_SIZE, {32767, 1, 32767, 1} },
	{ 5, TEGRA_DC_FEATURE_MAXIMUM_SCALE, {2, 2, 2, 2} },
	{ 5, TEGRA_DC_FEATURE_FILTER_TYPE, {1, 1} },
	{ 5, TEGRA_DC_FEATURE_LAYOUT_TYPE, {1, 0, 1} },
	{ 5, TEGRA_DC_FEATURE_INVERT_TYPE, {1, 1, 1} }, /* SCAN_COLUMN=true */
	{ 5, TEGRA_DC_FEATURE_FIELD_TYPE, {1} },
	{ 5, TEGRA_DC_FEATURE_COMPRESSION_FORMATS,
		{ TEGRA_WIN_FMT_COMPRESSION_T186_LOW,
		TEGRA_WIN_FMT_COMPRESSION_T186_HIGH } },
	{ 5, TEGRA_DC_FEATURE_PLANAR_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
	{ 5, TEGRA_DC_FEATURE_ROTATION_FORMATS,
			{ TEGRA_WIN_FMT_ROTATION_T186_LOW,
			TEGRA_WIN_FMT_ROTATION_T186_HIGH } },
	{ 5, TEGRA_DC_FEATURE_PACKED_ROTATION_MAXIMUM_SIZE,
		{5120, 1, 5120, 1} },
};

static struct tegra_dc_feature t186_feature_table_a = {
	ARRAY_SIZE(t186_feature_entries_a), t186_feature_entries_a,
};

void nvdisp_dc_feature_register(struct tegra_dc *dc)
{
	dc->feature = &t186_feature_table_a;
}
